package src;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件切割器和文件归并器
 */
public class FileSplitterAndMerger {

    /**
     * 切割文件并返回分割后的文件列表
     *
     * @param filePath 原始文件路径和名称
     * @param parts    分割成几个小文件
     * @return 分割后的文件列表
     * @throws IOException IO异常
     */
    public static List<File> splitFile(String filePath, int parts) throws IOException {
        List<File> splitFiles = new ArrayList<>();
        // 创建输入流
        FileInputStream fis = new FileInputStream(filePath);
        // 获取原始文件名称（不包含路径）
        String fileName = new File(filePath).getName();
        // 计算每一部分文件大小
        long partSize = (long) Math.ceil(((double) fis.available()) / parts);
        for (int i = 1; i <= parts; i++) {
            // 创建输出流
            FileOutputStream fos = new FileOutputStream(fileName.substring(0, fileName.lastIndexOf(".")) + "-" + i + ".bak");
            // 缓冲区大小设为 1KB
            byte[] buffer = new byte[1024];
            long count = 0;
            int n;
            while ((n = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, n);
                count += n;
                if (count >= partSize) {
                    break;
                }
            }
            // 保存每个切割出来的小文件
            splitFiles.add(new File(fileName.substring(0, fileName.lastIndexOf(".")) + "-" + i + ".bak"));
            fos.close();
        }
        fis.close();
        return splitFiles;
    }

    /**
     * 合并分割后的小文件，输出到指定路径和名称的文件
     *
     * @param splitFiles 存储小文件对象的列表
     * @param filePath   输出文件的路径和名称
     * @throws IOException IO异常
     */
    public static void mergeFiles(List<File> splitFiles, String filePath) throws IOException {
        // 创建输出流
        FileOutputStream fos = new FileOutputStream(filePath);
        for (File file : splitFiles) {
            // 创建输入流
            FileInputStream fis = new FileInputStream(file.getAbsolutePath());
            // 缓冲区大小设为 1KB
            byte[] buffer = new byte[1024];
            int n;
            while ((n = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, n);
            }
            fis.close();
        }
        fos.close();
    }

    public static void main(String[] args) {
        try {
            // 切割文件
            List<File> splitFiles = splitFile("src/test.txt", 5);
            // 合并小文件
            mergeFiles(splitFiles, "test_merged.txt");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
